// Redis Toolkit 基础使用示例

import { RedisToolkit } from '../src';
import { Cache, setCacheManager } from '../src/decorators/cache';
import { RateLimit, setRateLimitManager } from '../src/decorators/rateLimit';
import { Lock, setLockManager } from '../src/decorators/lock';

// 创建Redis Toolkit实例
const redis = new RedisToolkit({
  host: 'localhost',
  port: 6379,
  autoSerialize: true,
});

// 设置装饰器管理器
setCacheManager(redis.cache);
setRateLimitManager(redis.rateLimit);
setLockManager(redis.lock);

// 用户服务示例
class UserService {
  /**
   * 获取用户信息（带缓存）
   */
  @Cache({
    ttl: 300, // 5分钟缓存
    key: 'user:${args[0]}',
    tags: ['user']
  })
  async getUser(userId: string): Promise<any> {
    console.log(`Fetching user ${userId} from database...`);
    
    // 模拟数据库查询
    await new Promise(resolve => setTimeout(resolve, 100));
    
    return {
      id: userId,
      name: `User ${userId}`,
      email: `user${userId}@example.com`,
      createdAt: new Date(),
    };
  }

  /**
   * 更新用户信息（限流保护）
   */
  @(RateLimit({
    limit: 10,
    window: 60, // 每分钟最多10次
    key: 'update-user:${args[0]}'
  }) as any)
  async updateUser(userId: string, data: any): Promise<any> {
    console.log(`Updating user ${userId}...`);
    
    // 模拟数据库更新
    await new Promise(resolve => setTimeout(resolve, 50));
    
    // 清除用户缓存
    await redis.cache.invalidateByTag('user');
    
    return { success: true, userId, data };
  }

  /**
   * 删除用户（分布式锁保护）
   */
  @(Lock({
    key: 'delete-user:${args[0]}',
    ttl: 30
  }) as any)
  async deleteUser(userId: string): Promise<any> {
    console.log(`Deleting user ${userId}...`);
    
    // 模拟删除操作
    await new Promise(resolve => setTimeout(resolve, 200));
    
    // 清除相关缓存
    await redis.cache.del(`user:${userId}`);
    
    return { success: true, userId };
  }
}

// 游戏服务示例
class GameService {
  /**
   * 更新玩家分数
   */
  async updatePlayerScore(playerId: string, score: number): Promise<void> {
    await redis.leaderboard.updateScore('global-leaderboard', playerId, score);
    console.log(`Updated player ${playerId} score to ${score}`);
  }

  /**
   * 获取排行榜
   */
  async getLeaderboard(limit: number = 10): Promise<any[]> {
    return redis.leaderboard.getTopN('global-leaderboard', limit);
  }

  /**
   * 获取玩家排名
   */
  async getPlayerRank(playerId: string): Promise<number | null> {
    return redis.leaderboard.getRank('global-leaderboard', playerId);
  }
}

// 会话服务示例
class SessionService {
  /**
   * 创建用户会话
   */
  async createSession(userId: string, deviceInfo: any): Promise<string> {
    return redis.session.createSession(userId, {
      deviceId: deviceInfo.deviceId,
      userAgent: deviceInfo.userAgent,
      ipAddress: deviceInfo.ipAddress,
      data: { loginTime: new Date() },
    });
  }

  /**
   * 验证会话
   */
  async validateSession(sessionId: string): Promise<any> {
    const session = await redis.session.getSession(sessionId);
    
    if (!session) {
      throw new Error('Invalid session');
    }

    return session;
  }

  /**
   * 销毁会话
   */
  async destroySession(sessionId: string): Promise<void> {
    await redis.session.destroySession(sessionId);
  }
}

// 队列服务示例
class QueueService {
  /**
   * 添加邮件发送任务
   */
  async sendEmail(to: string, subject: string, body: string): Promise<string> {
    return redis.queue.addJob('email-queue', {
      type: 'send-email',
      payload: { to, subject, body },
      priority: 1,
    });
  }

  /**
   * 处理邮件队列
   */
  async processEmailQueue(): Promise<void> {
    const job = await redis.queue.getJob('email-queue');
    
    if (job) {
      try {
        console.log(`Processing email job ${job.id}:`, job.payload);
        
        // 模拟邮件发送
        await new Promise(resolve => setTimeout(resolve, 1000));
        
        await redis.queue.completeJob(job.id, { sent: true });
        console.log(`Email job ${job.id} completed`);
      } catch (error) {
        await redis.queue.failJob(job.id, error instanceof Error ? error.message : 'Unknown error');
        console.error(`Email job ${job.id} failed:`, error);
      }
    }
  }
}

// 计数器服务示例
class AnalyticsService {
  /**
   * 记录页面访问
   */
  async recordPageView(page: string, userId?: string): Promise<void> {
    // 全局页面访问计数
    await redis.counter.increment(`page-views:${page}`);
    
    // 每小时访问计数
    await redis.counter.incrementWindow(`page-views-hourly:${page}`, 3600);
    
    // 用户访问计数
    if (userId) {
      await redis.counter.increment(`user-page-views:${userId}:${page}`);
    }
  }

  /**
   * 获取页面访问统计
   */
  async getPageViewStats(page: string): Promise<any> {
    const [total, hourly] = await Promise.all([
      redis.counter.get(`page-views:${page}`),
      redis.counter.getWindowCount(`page-views-hourly:${page}`, 3600),
    ]);

    return { total, hourly };
  }
}

// 主函数示例
async function main() {
  try {
    // 连接Redis
    await redis.connect();
    console.log('Connected to Redis');

    // 创建服务实例
    const userService = new UserService();
    const gameService = new GameService();
    const sessionService = new SessionService();
    const queueService = new QueueService();
    const analyticsService = new AnalyticsService();

    // 用户服务示例
    console.log('\n=== User Service Examples ===');
    
    // 获取用户（第一次从数据库）
    const user1 = await userService.getUser('123');
    console.log('User 1:', user1);
    
    // 再次获取用户（从缓存）
    const user2 = await userService.getUser('123');
    console.log('User 2 (cached):', user2);
    
    // 更新用户
    await userService.updateUser('123', { name: 'Updated User' });

    // 游戏服务示例
    console.log('\n=== Game Service Examples ===');
    
    // 更新玩家分数
    await gameService.updatePlayerScore('player1', 1500);
    await gameService.updatePlayerScore('player2', 1200);
    await gameService.updatePlayerScore('player3', 1800);
    
    // 获取排行榜
    const leaderboard = await gameService.getLeaderboard(3);
    console.log('Leaderboard:', leaderboard);
    
    // 获取玩家排名
    const rank = await gameService.getPlayerRank('player1');
    console.log('Player1 rank:', rank);

    // 会话服务示例
    console.log('\n=== Session Service Examples ===');
    
    const sessionId = await sessionService.createSession('user123', {
      deviceId: 'device1',
      userAgent: 'Mozilla/5.0...',
      ipAddress: '192.168.1.1',
    });
    console.log('Created session:', sessionId);
    
    const session = await sessionService.validateSession(sessionId);
    console.log('Session data:', session);

    // 队列服务示例
    console.log('\n=== Queue Service Examples ===');
    
    const jobId = await queueService.sendEmail(
      'user@example.com',
      'Welcome!',
      'Welcome to our service!'
    );
    console.log('Email job created:', jobId);
    
    // 处理队列
    await queueService.processEmailQueue();

    // 分析服务示例
    console.log('\n=== Analytics Service Examples ===');
    
    await analyticsService.recordPageView('/home', 'user123');
    await analyticsService.recordPageView('/home', 'user456');
    await analyticsService.recordPageView('/about');
    
    const stats = await analyticsService.getPageViewStats('/home');
    console.log('Page view stats:', stats);

    // 健康检查
    console.log('\n=== Health Check ===');
    const health = await redis.healthCheck();
    console.log('Health status:', health);

    // 统计信息
    console.log('\n=== Statistics ===');
    const stats2 = await redis.getStats();
    console.log('Redis toolkit stats:', stats2);

  } catch (error) {
    console.error('Error:', error);
  } finally {
    // 断开连接
    await redis.disconnect();
    console.log('Disconnected from Redis');
  }
}

// 运行示例
if (require.main === module) {
  main().catch(console.error);
}

export {
  UserService,
  GameService,
  SessionService,
  QueueService,
  AnalyticsService,
};
